<?php
/**
 * @author  web_dxj@163.com
 * @time    2015-10-10 12:41
 */

class Categorys_model extends CI_Model {

    const CATEGORY_TREE  = 0;
    const CATEGORY_ARRAY = 1;

    public static $_TB_NAME = 'categorys';

    private $table_name      = 'categorys';
    private $category_array  = NULL ;



    public function __construct() {
        parent::__construct();
        $this->load->database();
        $this->initialize();
    }

    /**
     * 初始化数据
     */
    private function initialize() {
        // 加载categorymeta模型
        $this->load->model('categorymeta_model','categorymeta');
        $this->dg_get_category();
    }


    /**
     * 递归获取分类目录
     *
     * @param int $parent
     * @param int $deep
     * @return null
     */
    private function dg_get_category($parent = 0, $deep = 0) {

        static $_category_tree = array();

        $this->db->where('parent',$parent);
        $query = $this->db->get( $this->table_name );

        if ( 0 >= $query->num_rows())
        {
            return;
        }
        else
        {
            0 !== $parent && $deep ++ ;
        }

        foreach ( $query->result() as $row )
        {
            $row->deep = $deep;
            // merge other metas
            $metas = $this->categorymeta->get_category_metas($row->ID);

            if ( !empty($metas) )
            {
                foreach ($metas as $meta)
                {
                    $row->{$meta->meta_key} = $meta->meta_value;
                }
            }
            array_push($_category_tree,$row);
            $this->dg_get_category($row->ID,$deep);
        }

        $this->category_array = $_category_tree;
    }


    public function handler($delimiter = '&minus;&minus;') {
        if ( !is_null($this->category_array) )
        {
            foreach ( $this->category_array as $k => $category )
            {
                $this->category_array[$k]->category_name = str_repeat($delimiter,$category->deep) . $category->category_name ;
            }
        }

        return $this;
    }

    public function find($key,$value,$ID = NULL) {

        foreach ( $this->category_array as $category )
        {
            if ( $value == $category->{$key} )
            {
                if ( !is_null($ID) && intval($category->ID) === intval($ID) )
                {
                    continue;
                }

                return $category;
            }
        }

        return NULL;
    }


    /**
     * 递归处理重复值问题
     *
     * @param $key
     * @param $value
     * @param $delimiter
     * @param $ID
     * @return null
     */
    private function dg_handler_repeat($key, $value, $ID = NULL , $delimiter = '-') {

        if ( !empty($this->find($key,$value,$ID)) )
        {
            $value_arr = explode($delimiter,$value);
            if ( count($value_arr) >=2 )
            {
                $value_arr[count($value_arr) - 1 ] = intval(end($value_arr)) + 1;
                $value = implode($delimiter,$value_arr);
            }
            else
            {
                $value .= ($delimiter . '1');
            }

            $value = $this->dg_handler_repeat($key,$value,$ID);
        }

        return $value;
    }


    public function insert_category($data) {

        // handler category_name repeat
        $data['category_name'] = $this->dg_handler_repeat('category_name',$data['category_name']);
        // handler category_alias repeat
        $data['category_alias'] = $this->dg_handler_repeat('category_alias',$data['category_alias']);


        if ( FALSE !== $this->db->insert($this->table_name,$data))
        {
            // reload category model
            $this->initialize();
            return TRUE;
        }

        return FALSE;
    }

    public function update_category($data) {

        // handler category_name repeat
        $data['category_name'] = $this->dg_handler_repeat('category_name',$data['category_name'],$data['ID']);
        // handler category_alias repeat
        $data['category_alias'] = $this->dg_handler_repeat('category_alias',$data['category_alias'],$data['ID']);

        $this->db->where('ID',$data['ID']);
        unset($data['ID']);
        if ( FALSE !== $this->db->update($this->table_name,$data))
        {
            // reload category model
            // $this->initialize();
            return TRUE;
        }

        return FALSE;

    }

    /**
     * 删除分类
     * 多个ID请使用$delimiter定义的分隔符分开
     *
     * @param $ids_string
     * @param string $delimiter
     * @throws Exception
     * @return bool
     */
    public function del_category($ids_string,$delimiter = ',') {

        $ids_array = explode($delimiter,$ids_string);

        if (empty($ids_array))
        {
            throw new Exception('请传入要删除的分类的ID');
        }

        $count = 0;
        foreach ($ids_array as $ID)
        {
            // if id to hashids_encode, hashids_decode it,
            // else do nothing
            $ID = hashids_decode($ID);

            $this->handler_category_level($ID);
            $this->db->where('ID',$ID);
            if ( TRUE === $this->db->delete($this->table_name))
            {
                $count ++;
            }
        }

        return boolval($count);
    }


    /**
     * 更新菜单层级关系
     *
     * @param $ID
     */
    private function handler_category_level($ID) {
        $del = $this->find('ID',$ID);
        if (empty($del))
        {
            return;
        }

        foreach ($this->category_array as $category)
        {
            if ( $ID === intval($category->parent) )
            {
                $this->db->where('ID',$category->ID);
                $this->db->update($this->table_name,array('parent' => $del->parent));
            }
        }
    }


    public function get_category() {
        return $this->category_array;
    }


    public function get_category_arr_by_ids($ids_array) {
        if (!count($ids_array))
        {
            return NULL;
        }

        $search_result = array();
        foreach ( $this->category_array  as $item )
        {
            if ( in_array($item->ID,$ids_array) )
                $search_result[] = $item;
        }

        if (!count($search_result))
        {
            return NULL;
        }

        return $search_result;
    }
}